package org.funtester.performance.books.chapter11.section3;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.*;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
 * 队列JMH测试
 */
@BenchmarkMode(Mode.Throughput)// 制定运行测试模式,当前为吞吐量模式
@State(value = Scope.Thread)//默认为Scope.Thread,含义是每个线程都会有一个实例
@Warmup(iterations = 1, time = 1, timeUnit = TimeUnit.SECONDS)//预热次数,含义是每个测试会跑多久
@Measurement(iterations = 1, batchSize = 1)//测试迭代次数,批次大小
@Threads(100)//测试线程数
@Fork(value = 1, jvmArgs = {"-Xms4G", "-Xmx4G"})//fork表示每个测试会fork出几个进程
@OutputTimeUnit(TimeUnit.MICROSECONDS)//输出时间单位
public class QueueTest {

    @Param({"1000", "10000", "100000"})//测试参数
    public int length;

    List<Integer> arrayList = new ArrayList();

    List<Integer> linkedList = new LinkedList<>();

    Vector<Integer> vector = new Vector();

    LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue();

    LinkedBlockingDeque<Integer> linkedBlockingDeque = new LinkedBlockingDeque();

    PriorityQueue<Integer> priorityQueue = new PriorityQueue();

    @Setup
    public void setup() {//初始化方法
        for (int i = 0; i < length; i++) {
            arrayList.add(i);//添加元素
            linkedList.add(i);//添加元素
            linkedBlockingQueue.add(i);//添加元素
            linkedBlockingDeque.add(i);//添加元素
            priorityQueue.add(i);//添加元素
        }
    }

    @Benchmark
    public void arrayList() {//ArrayList测试方法
        int i = ThreadLocalRandom.current().nextInt(length);
        arrayList.add(i);
        arrayList.remove(0);
    }

    @Benchmark
    public void linkedList() {//LinkedList测试方法
        int i = ThreadLocalRandom.current().nextInt(length);
        linkedList.add(i);
        linkedList.remove(0);
    }

    @Benchmark
    public void vector() {//Vector测试方法
        int i = ThreadLocalRandom.current().nextInt(length);
        vector.add(i);
        vector.remove(0);
    }

    @Benchmark
    public void linkedBlockingQueue() {//LinkedBlockingQueue测试方法
        int i = ThreadLocalRandom.current().nextInt(length);
        linkedBlockingQueue.add(i);
        linkedBlockingQueue.poll();
    }

    @Benchmark
    public void linkedBlockingDeque() {//LinkedBlockingDeque测试方法
        int i = ThreadLocalRandom.current().nextInt(length);
        linkedBlockingDeque.add(i);
        linkedBlockingDeque.poll();
    }

    @Benchmark
    public void priorityQueue() {//PriorityQueue测试方法
        int i = ThreadLocalRandom.current().nextInt(length);
        priorityQueue.add(i);
        priorityQueue.poll();
    }

    public static void main(String[] args) throws RunnerException {
        Options options = new OptionsBuilder()
                .include(QueueTest.class.getSimpleName())//测试类名
                .result("result.json")//测试结果输出到result.json文件
                .resultFormat(ResultFormatType.JSON)//输出格式
                .build();
        new Runner(options).run();
    }

}
